package root.electronclass.electronclass.grade.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.lifecycle.map
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import root.electronclass.electronclass.ext.CoroutineExceptionHandler
import root.electronclass.electronclass.ext.chineseNumber
import root.electronclass.electronclass.ext.toDateMMdd
import root.electronclass.electronclass.ext.toDateYyyyMMdd
import root.electronclass.electronclass.grade.model.ClassCurriculumItem
import root.electronclass.electronclass.grade.model.ClassDateGroup
import root.electronclass.electronclass.grade.repository.ClassRepository
import java.util.Calendar

/**
 *
 * @author Lokiy
 * @date 2023/2/4 14:07
 */
class ClassCurriculumViewModel : ViewModel() {

    /**
     * -1 上一周 0本周 1下一周
     */
    private val type = MutableLiveData(WeekType.CURRENT)

    /**
     * 原始数据
     */
    private val originData = MutableLiveData<Pair<LinkedHashMap<String, List<ClassCurriculumItem>>, Calendar>>()
    val curriculumData = originData.map {
        it.first
    }

    private val _data = originData.map {
        val list = mutableListOf<ClassDateGroup<ClassCurriculumItem>>()
        val result = it.first
        val calendar = it.second
        for (i in 0..2) {
            val weekDateList = (0 until 7).map {
                (result[calendar.timeInMillis.toDateYyyyMMdd()] ?: mutableListOf()).also {
                    calendar.add(Calendar.DAY_OF_YEAR, 1)
                }
            }
            list.add(ClassDateGroup(i.toLong(), flatCurriculumItems(weekDateList)))
        }
        list
    }
    val data: LiveData<List<ClassCurriculumItem>> = Transformations.switchMap(type) {
        Transformations.map(_data) { list ->
            list.getOrNull(it.type + 1)?.data ?: mutableListOf()
        }
    }
    val titleData: LiveData<List<String>> = Transformations.map(data) { list ->
        list.filterIndexed { index, _ -> index % 7 == 0 }
            .map { it.showTime }
    }
    val weekData: LiveData<List<ClassCurriculumItem>> = Transformations.map(type) { type ->
        val calendar = Calendar.getInstance()
        val list = mutableListOf<ClassCurriculumItem>()
        calendar.add(Calendar.DAY_OF_YEAR, type.type * 7)
        //1 周日 2周一 3周二 4周三
        val dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK)
        if (dayOfWeek >= 2) {
            calendar.add(Calendar.DAY_OF_YEAR, -(dayOfWeek - 2))
        } else {
            calendar.add(Calendar.DAY_OF_YEAR, -6)
        }
        val now = Calendar.getInstance().timeInMillis.toDateYyyyMMdd()
        for (i in 1..7) {
            val name = /*if (calendar.timeInMillis.toDateYyyyMMdd() == now) "今天" else */"周" + i.chineseNumber.replace("七", "日")
            if (calendar.timeInMillis.toDateYyyyMMdd() == now) {
                list.add(ClassCurriculumItem(name + "今天", calendar.timeInMillis.toDateMMdd(), ""))
            } else {
                list.add(ClassCurriculumItem(name, calendar.timeInMillis.toDateMMdd(), ""))
            }
            calendar.add(Calendar.DAY_OF_YEAR, 1)
        }

        list
    }

    /**
     * 加载班级荣耀
     */
    fun load() {
        viewModelScope.launch(CoroutineExceptionHandler()) {
            originData.value = ClassRepository.getClassCurriculum()
        }
    }

    private fun flatCurriculumItems(lastWeekDateList: List<List<ClassCurriculumItem>>): MutableList<ClassCurriculumItem> {
        val maxLength = lastWeekDateList.maxOf { it.size }
        val data = mutableListOf<ClassCurriculumItem>()
        for (i in 0 until maxLength) {
            //rows
            lastWeekDateList.forEachIndexed { _, classCurriculumItems ->
                //column
                data.add(classCurriculumItems.getOrNull(i) ?: ClassCurriculumItem.EMPTY)
            }
        }
        return data
    }

    fun loadData(weekType: WeekType) {
        if (type.value != weekType) {
            type.value = weekType
        }
    }
}

enum class WeekType(val type: Int) {
    LAST(-1), CURRENT(0), NEXT(1);

}
